﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace zykControl
{
    public partial class FrmUIBindingTotal
    {
        /// <summary>
        /// 设置界面控件的数据绑定
        /// </summary>
        public FrmUIBindingTotal()
        {
            InitializeComponent();
        }

        private List<CFrmUIBindingTotalItem> mList = [];

        /// <summary>
        /// 设置界面控件的数据绑定
        /// </summary>
        /// <param name="theOwner"></param>
        public static void ShowA(UIBinding theOwner)
        {
            var dI = new FrmUIBindingTotal();
            dI.dgvControl.AutoGenerateColumns = false;
            dI.dgvModel.AutoGenerateColumns = false;
            dI.Text = "UIBinding数据绑定项总览 - 模型类名: " + theOwner.ObjectName;
            dI.RefreshList(theOwner);
            dI.ShowDialog();
        }
        private static readonly string[] UpdateMode = ["标准", "实时", "不更新"];

        private void RefreshList(UIBinding theOwner)
        {
            var dControls = theOwner.GetControls();
            var dList = new List<CFrmUIBindingTotalItem>();
            foreach (var dControl in dControls)
            {
                var dFields = theOwner.GetDataField(dControl);
                if (dFields == null) continue;
                foreach (var dField in dFields)
                {
                    var dItem = new CFrmUIBindingTotalItem(
                        dControl.Name,
                        dField.PropertyName, dField.DataField,
                        UpdateMode[(int)dField.UpdateMode],
                        dField.FormatString,
                        dField.NullText
                    );
                    dList.Add(dItem);
                }
            }

            mList = dList;
            var dControlList = from dItem in dList
                               group dItem by dItem.ControlName into g
                               let ctrlname = g.Key
                               select new { id = ctrlname, text = ctrlname + " (" + g.Count() + ")" };
            lsvControl.Items.Clear();
            foreach (var dItem in dControlList)
            {
                var dListItem = lsvControl.Items.Add(dItem.text);
                dListItem.Name = dItem.id;
            }

            var dModelList = from dItem in dList
                             group dItem by dItem.FieldName into Group
                             let modelname = Group.Key
                             select new { id = modelname, text = modelname + " (" + Group.Count() + ")" };
            lsvModel.Items.Clear();
            foreach (var dItem in dModelList)
            {
                var dListItem = lsvModel.Items.Add(dItem.text);
                dListItem.Name = dItem.id;
            }

            RefreshModel();
            RefreshControl();
        }

        private void RefreshControl()
        {
            if (lsvControl.SelectedItems.Count == 0)
            {
                dgvControl.DataSource = null;
            }
            else
            {
                string dID = lsvControl.SelectedItems[0].Name;
                var dList = from dItem in mList
                            where (dItem.ControlName ?? "") == (dID ?? "")
                            select new CFrmUIBindingTotalControl()
                            {
                                FieldName = dItem.FieldName,
                                FormatString = dItem.FormatString,
                                NullText = dItem.NullText,
                                PropertyName = dItem.PropertyName,
                                UpdateMode = dItem.UpdateMode
                            };
                var dBindingList = new BindingList<CFrmUIBindingTotalControl>([.. dList]);
                dgvControl.DataSource = dBindingList;
            }
        }

        private void RefreshModel()
        {
            if (lsvModel.SelectedItems.Count == 0)
            {
                dgvModel.DataSource = null;
            }
            else
            {
                string dID = lsvModel.SelectedItems[0].Name;
                var dList = from dItem in mList
                            where (dItem.FieldName ?? "") == (dID ?? "")
                            select new CFrmUIBindingTotalModel()
                            {
                                ControlName = dItem.ControlName,
                                FormatString = dItem.FormatString,
                                NullText = dItem.NullText,
                                PropertyName = dItem.PropertyName,
                                UpdateMode = dItem.UpdateMode
                            };
                var dBindingList = new BindingList<CFrmUIBindingTotalModel>([.. dList]);
                dgvModel.DataSource = dBindingList;
            }
        }

        private void LsvControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshControl();
        }

        private void LsvModel_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshModel();
        }
    }

    public record CFrmUIBindingTotalItem(string ControlName, string PropertyName, string FieldName, string UpdateMode, string FormatString, string NullText)
    {
        //public string ControlName { get; set; }
        ///// <summary>控件的属性名</summary>
        //public string PropertyName { get; set; }
        ///// <summary>模型的属性名</summary>
        //public string FieldName { get; set; }
        //public string UpdateMode { get; set; }
        //public string FormatString { get; set; }
        //public string NullText { get; set; }
    }

    public class CFrmUIBindingTotalControl : INotifyPropertyChanged
    {
        private string mPropertyName = "";
        /// <summary>控件的属性名</summary>
        public string PropertyName
        {
            get
            {
                return mPropertyName;
            }

            set
            {
                mPropertyName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PropertyName)));
            }
        }

        private string mFieldName = "";
        /// <summary>模型的属性名</summary>
        public string FieldName
        {
            get
            {
                return mFieldName;
            }

            set
            {
                mFieldName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FieldName)));
            }
        }

        private string mUpdateMode = "";

        public string UpdateMode
        {
            get
            {
                return mUpdateMode;
            }

            set
            {
                mUpdateMode = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UpdateMode)));
            }
        }

        private string mFormatString = "";

        public string FormatString
        {
            get
            {
                return mFormatString;
            }
            set
            {
                mFormatString = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FormatString)));
            }
        }

        private string mNullText = "";

        public string NullText
        {
            get
            {
                return mNullText;
            }
            set
            {
                mNullText = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NullText)));
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
    }

    public class CFrmUIBindingTotalModel : INotifyPropertyChanged
    {
        private string mPropertyName = "";
        /// <summary>控件的属性名</summary>
        public string PropertyName
        {
            get
            {
                return mPropertyName;
            }
            set
            {
                mPropertyName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PropertyName)));
            }
        }

        private string mControlName = "";
        /// <summary>控件名</summary>
        public string ControlName
        {
            get
            {
                return mControlName;
            }
            set
            {
                mControlName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ControlName)));
            }
        }

        private string mUpdateMode = "";

        public string UpdateMode
        {
            get
            {
                return mUpdateMode;
            }
            set
            {
                mUpdateMode = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UpdateMode)));
            }
        }

        private string mFormatString = "";

        public string FormatString
        {
            get
            {
                return mFormatString;
            }
            set
            {
                mFormatString = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FormatString)));
            }
        }

        private string mNullText = "";

        public string NullText
        {
            get
            {
                return mNullText;
            }
            set
            {
                mNullText = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NullText)));
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
    }
}